package com.allin.http;

import android.content.Context;
import android.os.AsyncTask;
import android.text.TextUtils;

import com.allin.http.callback.ResultCallback;
import com.allin.http.tools.NetUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.ref.WeakReference;

/**
 * Description:
 *
 * @author: liangyuanqi
 * @date: 2016/4/19 16:21
 */
public class CacheManager {
    /**wifi缓存时间为半小时*/
    private static long wifi_cache_time = 30 * 60 * 1000;

    /**3G缓存时间为2小时*/
    private static long g3_cache_time = 2 * 60 * 60 * 1000;

    /**无网络缓存时间为48小时*/
    private static long error_cache_time = 48 * 60 * 60 * 1000;

    /**
     *  保存对象
     * @param context
     * @param ser
     * @param file
     * @return
     */
    public static boolean saveObject(Context context,Serializable ser,String file){
        FileOutputStream fos=null;
        ObjectOutputStream oos=null;
        try{
            fos=context.openFileOutput(file,Context.MODE_PRIVATE);
            oos=new ObjectOutputStream(fos);
            oos.writeObject(ser);
            oos.flush();
            return true;
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try{
                oos.close();
                fos.close();
            }catch(Exception e){
            }
        }
        return false;
    }

    /**
     * 读取对象
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static Serializable readObject(Context context,String file){
        if(!isExistDataCache(context,file)){
            return null;
        }
        FileInputStream fis=null;
        ObjectInputStream  ois=null;
        try{
            fis=context.openFileInput(file);
            ois=new ObjectInputStream(fis);
            return (Serializable) ois.readObject();
        }catch(FileNotFoundException e){
        }catch(Exception e){
            e.printStackTrace();
            if(e instanceof InvalidClassException){
                File data=context.getFileStreamPath(file);
                data.delete();
            }
        }
        return null;
    }

    /**
     * 清理缓存
     * @param context
     * @param cacheKey 缓存名称
     */
    public static void cleanCacheByKey(Context context,String cacheKey){
        File directory=context.getFilesDir();
        if (directory != null && directory.exists() && directory.isDirectory()) {
            cacheKey=cacheKey!=null?cacheKey.substring(0,cacheKey.indexOf("_")):"";
            for (File child : directory.listFiles()) {
                String name=child.getName();
                if (!child.isDirectory() && name.startsWith("cache")) {
                    if(!TextUtils.isEmpty(cacheKey) && name.startsWith(cacheKey)){
                        child.delete();
                    }
                }
            }
        }
    }
    /**
     * 判断缓存是否存在
     * @param cachefile
     * @return
     */
    public static boolean isExistDataCache(Context context, String cachefile) {
        if (context == null)
            return false;
        boolean exist = false;
        File data = context.getFileStreamPath(cachefile);
        if (data.exists())
            exist = true;
        return exist;
    }

    /**
     * 判断缓存是否已经失效
     */
    public static boolean isCacheDataValid(Context context, String cachefile) {
        return isCacheDataValid(context,cachefile,0);
    }

    /**
     * 判断缓存是否有效
     * @param context
     * @param cachefile 缓存文件名称
     * @param cacheTime  缓存时间
     * @return
     */
    public static boolean isCacheDataValid(Context context, String cachefile,long cacheTime) {
        if (context == null){
            return false;
        }
        File data = context.getFileStreamPath(cachefile);
        if (!data.exists()) {
            return false;
        }
        long existTime = System.currentTimeMillis() - data.lastModified();
        boolean valid = false;
        if(cacheTime<=0){
            if(!NetUtil.isNetworkAvailable(context)){
                cacheTime=error_cache_time;
            }else if(NetUtil.is3rd(context)){
                cacheTime=g3_cache_time;
            }else if(NetUtil.isWifi(context)){
                cacheTime=wifi_cache_time;
            }else{
                cacheTime=wifi_cache_time;
            }
        }


        valid = existTime > cacheTime ? false : true;
        return valid;
    }

    /**
     * 缓存数据
     */
    public class SaveCacheTask extends AsyncTask<String, Void, Void> {
        private final WeakReference<Context> mContext;
        private final Serializable seri;

        public SaveCacheTask(Context context, Serializable seri) {
            mContext = new WeakReference<Context>(context);
            this.seri = seri;
        }

        @Override
        protected Void doInBackground(String... params) {
            CacheManager.saveObject(mContext.get(), seri, params[0]);
            return null;
        }
    }

    /**
     * 读取缓存
     */
    public class ReadCacheTask extends AsyncTask<String, Void, Object> {
        private final WeakReference<Context> mContext;
        ResultCallback callback;
        String afterCode;//执行after时返回码
        public ReadCacheTask(Context context) {
            mContext = new WeakReference<Context>(context);
        }
        public ReadCacheTask(Context context,ResultCallback callback,String afterCode) {
            mContext = new WeakReference<Context>(context);
            this.callback=callback;
            this.afterCode=afterCode;
        }
        @Override
        protected Object doInBackground(String... params) {
            if(mContext!=null){
                Serializable seri = CacheManager.readObject(mContext.get(),params[0]);
                return seri;
            }
            return null;
        }

        @Override
        protected void onPostExecute(Object obj) {
            super.onPostExecute(obj);
            onLoadDataSuccess(callback,obj,afterCode);
        }
    }

    protected void onLoadDataSuccess(ResultCallback callback, Object data,String afterCode) {
        callback.onBefore(null);
        callback.onResponse(data);
        afterCode= TextUtils.isEmpty(afterCode)?"102":afterCode;
        callback.onAfter(afterCode);
    }


}
